#include <iostream>
#include <string>
#include <vector>

#include <map>

using namespace std ;

typedef vector<string> Path ;

class Node ;

class Node
{
public:
typedef map<string,Node > NodeContainer ;
public:
    void set_value(const string& value)
    {
        m_value = value ;
    }
 
    const string& get_value() const
    {
        return m_value ;
    } 

    const NodeContainer& get_child_container() const 
    {
        return m_child ;
    }

    const Node* find_child(const string& key)  const 
    {
        auto it = m_child.find(key) ;
        if(it == m_child.end() ) return NULL ;

        return &it->second ;
    }

    Node* add_child(const string& key)
    {
        return &m_child[key] ;

    } 

    void remove_child(const string& key)
    {
        m_child.erase(key) ;
    }
    
private:
    string m_value ;
    NodeContainer m_child ;
    

} ;


typedef map<string,string> ChildDataContainer ;

class Tree
{
public:
    int set(const Path& path,const string& data)
    {
        Node* node = &m_root ;
        for(auto const& value : path)
        {
            node = node->add_child(value) ;
            if(node == NULL ) return -1;
        }
        
        node->set_value(data) ;
        return 0 ;
        
    }
 
    void erase(const Path& path) 
    {

        const Node* parent_node = &m_root ;
        const Node* node = &m_root ;
        for(auto const& value : path)
        {
            parent_node = node ;
            node = node->find_child(value) ;
            if(node == NULL) return ;
        }

        const_cast<Node*>(parent_node)->remove_child(path[path.size()-2]) ;
        
    }

    const string& get_data(const Path& path) const 
    {
        const Node* node = &m_root ;
        for(auto const& value : path)
        {
            node = node->find_child(value) ;
            if(node == NULL) return "";
        }

        return node->get_value() ;


    }

    int get_child_data(const Path& path,ChildDataContainer& child_data) const 
    {
        const Node* node = &m_root ;
        for(auto const& value : path)
        {
            node = node->find_child(value) ;
            if(node == NULL) return -1;
        }

        child_data.clear() ;
        const Node::NodeContainer& child = node->get_child_container() ;
        for( auto const& it : child )
        {
            child_data[it.first] = it.second.get_value() ;
        }
    
        return 0 ;

    }

private:
    Node m_root ;

} ;

Path string2path(const string& src_str,char delemiter= '.')
{
    Path path ;
    if (src_str.size() == 0)  return path;

    string::size_type  pos = 0;
    string::size_type  flag_pos = src_str.find_first_of(delemiter);

    while (flag_pos != string::npos)
    {
        path.push_back(src_str.substr(pos, flag_pos-pos));
        pos = flag_pos + 1;

        flag_pos = src_str.find_first_of(delemiter, pos);
    }
    path.push_back(src_str.substr(pos));

    return path;    

}

void output_child_data(const ChildDataContainer& child_data)
{
    for(auto const& it : child_data)
    {
        cout << it.first << "=" << it.second << endl ;
    }


}

int main()
{
    Tree tree ;
    Path path = string2path("game.global.guild") ;
    tree.set(path,"game.global.guild") ;
    
    path = string2path("game.global.test") ;
    tree.set(path,"game.global.test") ;

    path = string2path("game.global.test1.hello") ;
    tree.set(path,"game.global.test1.hello") ;

    ChildDataContainer child_data ;

    path = string2path("game.global") ;
    tree.get_child_data(path,child_data) ;
    output_child_data(child_data) ;

    path = string2path("game.global.test1") ;
    tree.get_child_data(path,child_data) ;
    output_child_data(child_data) ;
    return 0 ;
    
}


